package nl.cypherpunk.statefuzzer.fuzzing;

import net.automatalib.words.Word;
import nl.cypherpunk.statefuzzer.mealyDot.MealyState;

import java.util.*;

public class FuzzingPath {
    List<MealyState> statePath;
    Random  rand;
    List<byte[]> messages;
    Word<String> symbols;
    ArrayList<byte[]> seed;
    public ArrayList<Double> seedScore;
    public int fuzzs;
    public double score;
    public int coverageAdd;
    public ArrayList<List<byte[]>> messagesList;
    public ArrayList<Double> messagesScore;
    public FuzzingPath(List<MealyState> statePath, List<byte[]> messages, Word<String> symbols){
        this.statePath = statePath;
        rand = new Random();
        fuzzs = 0;
        score = 0.0;
        coverageAdd = 0;
        this.messages = messages;
        this.symbols = symbols;
        seed = new ArrayList<>();
        seedScore = new ArrayList<>();
        this.messagesList = new ArrayList<>();
        this.messagesScore = new ArrayList<>();
    }

    public void addSeed(byte[] message){
        seed.add(message);
        seedScore.add(10.0);
    }

    public byte[] getMessage(int index){
        return messages.get(index);
    }

    public String getSymbol(int index){
        return symbols.getSymbol(index);
    }

    public Integer getRandomIndex(ArrayList<Double> map){
        NavigableMap<Double, Integer> hashMap = new TreeMap<>();
        double total = 0;
        for (int i = 0; i < map.size(); i++) {
            total += map.get(i);
            hashMap.put(total, i);
        }
        Double weight = 1.0 * rand.nextInt((int) total);
        return hashMap.ceilingEntry(weight).getValue();
    }

    public void addScore(double score){
        this.score += score;
    }

    public void addSeedScore(int index, double score){
        seedScore.set(index,seedScore.get(index)+score);
    }

    public void addMessages(List<byte[]> messages, double score) {
        messagesList.add(messages);
        messagesScore.add(score);
    }

    public void delMessageScore(int index, double score){
        messagesScore.set(index,messagesScore.get(index)-score);
    }
}
